package gzx.specialcomponents
{
	import spark.components.Group;
	import spark.components.HGroup;
	import spark.components.Label;
	import spark.components.VGroup;
	import events.ChartItemClickEvent;
	import mx.core.UIComponent;
	import mx.events.ResizeEvent;
	import spark.components.BorderContainer;
	import flash.utils.Dictionary;
	import flash.events.MouseEvent;
	
	[Event(name="ItemClick", type="events.ChartItemClickEvent")]
	public class SequenceDiagram extends Group
	{
		private var groupLegends:Array = new Array();
		private var groupCharts:Array = new Array();
		private var chartInfos:Array = new Array();
		private var serialDes:Dictionary = new Dictionary();
		private var legends:Array = new Array();
		private var points:Array = new Array();
		private var selLines:Array = new Array();
		private var selectedPoint:PointInfo = null;
		private var selectedPointIndex:int =-1;
		
		public function SequenceDiagram()
		{
			super();
			this.minHeight = 200;
			this.minWidth = 400;
			this.percentWidth = 100.0;
			this.percentHeight = 100.0;
			this.addEventListener("resize", this_resizeHandler);
		}
		public function set ChartInfos(value:Array):void
		{
			this.chartInfos = value;
			createGroups();
			drawLegend();
		}
		public function set SerialDes(value:Dictionary):void
		{
			this.serialDes = value;
		}
		public function set PointInfos(value:Array):void
		{
			this.points = value;
			selectedPointIndex = -1;
			selLines.splice(0);
			drawGraph();
		}
		public function get SelectedPoint():PointInfo
		{
			return selectedPoint;
		}
		
		public function SelectedPointByID(value:int):void
		{
			if(points!=null)
			{
				var i:int=0;
				var length:int = points.length;
				for(i;i<length;i++)
				{
					if((points[i] as PointInfo).RelayID == value)
					{
						selectedPoint = points[i] as PointInfo;
						fireSelectedPointChanged(i);
						break;
					}
				}
			}
		}
		
		public function set SelectedPointIndex(value:int):void
		{
			if(points!=null && points.length>value)
			{
				selectedPointIndex = value;
				this.selectedPoint = points[value] as PointInfo;
				fireSelectedPointChanged(value);
			}
		}
		
		private function drawGraph():void
		{
			for each(var chart:Group in groupCharts)
			{
				if(chart!=null)
				{
					chart.removeAllElements();
				}
			}
			if(points == null || points.length == 0) { return; }
			for (var i:int=0;i<chartInfos.length;i++)
			{
				var chartInfo:ChartInfo = chartInfos[i] as ChartInfo;
				if (chartInfo != null)
				{
					var group:Group = groupCharts[i];
					var segWidth:int = group.width;
					var segHeight:int = group.height;
					//画中间线
					var lineChart:UIComponent = new UIComponent();
					group.addElement(lineChart);
					lineChart.graphics.lineStyle(1,0xCCCCCC);
					
					lineChart.graphics.moveTo(0,segHeight / 4);
					lineChart.graphics.lineTo(segWidth,segHeight / 4);
					lineChart.graphics.moveTo(0,segHeight/2);
					lineChart.graphics.lineTo(segWidth,segHeight/2);
					lineChart.graphics.moveTo(0, segHeight / 4 * 3);
					lineChart.graphics.lineTo(segWidth,segHeight / 4 * 3);
					
					var si:int = 0;
					var slenght:int = chartInfo.SerialInfos.length;
					for (si;si<slenght;si++)
					{
						var serialInfo:ChartSerialInfo = chartInfo.SerialInfos[si] as ChartSerialInfo;
						var region:Number = (segHeight - 1)/(serialInfo.Max - serialInfo.Min);
						if(serialDes[serialInfo.Name]==null)
						{
							continue;
						}
						var xx:int = serialDes[serialInfo.Name] as int;
						var pi:int = 0;
						var plength:int = points.length;
						if(serialInfo.DisplayType == ChartSerialInfo.Line)
						{
							var chartLine:UIComponent = new UIComponent();
							group.addElement(chartLine);
							chartLine.graphics.lineStyle(serialInfo.LineWidth,serialInfo.Color);
							var isNewLine:Boolean = true;
							for (pi =0;pi<plength;pi++)
							{
								var pointInfoLine:PointInfo = points[pi] as PointInfo;
								var pointx:int = pi*2;
								var pointInfoLineY:Number = pointInfoLine.Serials[xx] as Number;
								if(!isNaN(pointInfoLineY))
								{
									var pointLiney:Number = (serialInfo.Max - pointInfoLineY) * region;
									if(isNewLine)
									{
										chartLine.graphics.moveTo(pointx, pointLiney);
										chartLine.graphics.lineTo(pointx+1, pointLiney);
										isNewLine = false;
									}
									else
									{
										chartLine.graphics.lineTo(pointx, pointLiney);
										chartLine.graphics.lineTo(pointx+1, pointLiney);
									}
								}else
								{
									isNewLine = true;
								}
								pointInfoLine.x = pointx;
							}
						}
						else
						{
							var charArea:UIComponent = new UIComponent();
							group.addElement(charArea);
							charArea.graphics.beginFill(serialInfo.Color);
							charArea.graphics.moveTo(0, segHeight);
							for (pi =0;pi<plength;pi++)
							{
								var pointInfoArea:PointInfo = points[pi] as PointInfo;
								var pointInfoAreaY:Number = pointInfoArea.Serials[xx] as Number;
								var pointAreay:Number = (serialInfo.Max - pointInfoAreaY) * region;
								var pointAreax:int = pi*2;
								charArea.graphics.lineTo(pointAreax, pointAreay);
								pointInfoArea.x = pointAreax;
								if(pi==plength-1)
								{
									charArea.graphics.lineTo(pi*2,segHeight);
									charArea.graphics.lineTo(0, segHeight);
								}
							}
							charArea.graphics.endFill();
						}
					}
				}
			}
			if(selectedPointIndex>-1)
			{
				SelectedPointIndex = selectedPointIndex;
			}
		}
		
		private function drawLegend():void
		{
			for each(var legend:Group in groupLegends)
			{
				if(legend!=null)
				{
					legend.removeAllElements();
				}
			}
			
			for (var i:int=0;i<chartInfos.length;i++)
			{
				var chartInfo:ChartInfo = chartInfos[i] as ChartInfo;
				if (chartInfo != null)
				{
					var group:Group = groupLegends[i] as Group;
					var segHeight:int = group.height;
					var widthOffset:int = 0;
					for each (var serialInfo:ChartSerialInfo in chartInfo.SerialInfos)
					{
						var labelMin:Label = new Label();
						labelMin.text = serialInfo.Min.toString();
						labelMin.setStyle("color",0x0000FF);
						labelMin.x = widthOffset;
						labelMin.y = group.height - 12;
						group.addElement(labelMin);
						
						var labelMax:Label = new Label();
						labelMax.text = serialInfo.Max.toString();
						labelMax.setStyle("color",0x0000FF);
						labelMax.x=widthOffset;
						labelMax.y= 2;
						group.addElement(labelMax);
						
						var lineLegend:UIComponent = new UIComponent();
						group.addElement(lineLegend);
						lineLegend.graphics.lineStyle(1,serialInfo.Color);
						
						lineLegend.graphics.moveTo(widthOffset + 20,0);
						lineLegend.graphics.lineTo(widthOffset + 25, 0);
						lineLegend.graphics.moveTo(widthOffset + 20, segHeight / 4);
						lineLegend.graphics.lineTo(widthOffset + 25, segHeight / 4);
						lineLegend.graphics.moveTo(widthOffset + 20, segHeight / 2);
						lineLegend.graphics.lineTo(widthOffset + 25, segHeight / 2);
						lineLegend.graphics.moveTo(widthOffset + 20, segHeight * 3 / 4);
						lineLegend.graphics.lineTo(widthOffset + 25, segHeight * 3 / 4);
						lineLegend.graphics.moveTo(widthOffset + 20, segHeight - 1);
						lineLegend.graphics.lineTo(widthOffset + 25, segHeight - 1);
						lineLegend.graphics.moveTo(widthOffset + 25,0);
						lineLegend.graphics.lineTo(widthOffset + 25, segHeight - 1);
						
						var legendName:Label = new Label();
						legendName.text = serialInfo.Name;
						legendName.setStyle("color",0x0000FF);
						legendName.x=widthOffset + 40;
						legendName.y= 3;
						legendName.rotation = 90;
						group.addElement(legendName);
						
						widthOffset += 42;
					}
				}
			}
		}
		//画GROUP，每一个块都是由GROUP组成的
		private function createGroups():void
		{
			groupCharts.splice(0);
			groupLegends.splice(0);
			this.removeAllElements();
			//周围空出3像素
			var mainHeight:int = this.height -6;
			var mainWidth:int = this.width -6;
			//取最大的Legend作为Legend的长度
			var legendWidth:int = getMaxLegend()*42;
			//从坐标轴为3,3开始
			var chartsLength:int = chartInfos.length;
			for(var i:int=0; i<chartInfos.length; i++)
			{
				var contentWidth:int = mainWidth-legendWidth -6;
				//包含边框的每个高度
				var contentHeight:int = (mainHeight - chartsLength*4 +2)/chartsLength;//chartsLength*4边框加空隙高度 再加上2个才一个空隙
				var margintop:int = 3+(contentHeight+4)*i;//2个边框宽度加2个空隙
				
				var chartBorder:UIComponent = new UIComponent();
				chartBorder.graphics.lineStyle(1,0x696969);
				chartBorder.graphics.moveTo(3,margintop); //2为空隙
				chartBorder.graphics.lineTo(5+contentWidth,margintop);
				chartBorder.graphics.lineTo(5+contentWidth,margintop+contentHeight+1);
				chartBorder.graphics.lineTo(3,margintop+contentHeight+1);
				chartBorder.graphics.lineTo(3,margintop);
				this.addElement(chartBorder);
				
				var chartGroup:Group = new Group();
				chartGroup.x = 4;
				chartGroup.y = margintop+1;
				chartGroup.height = contentHeight;
				chartGroup.width = contentWidth;
				chartGroup.addEventListener(MouseEvent.CLICK,chart_clickHandler);
				this.addElement(chartGroup);
				
				var legendBorder:UIComponent = new UIComponent();
				legendBorder.graphics.lineStyle(1,0x696969);
				legendBorder.graphics.moveTo(contentWidth+7,margintop);
				legendBorder.graphics.lineTo(contentWidth+legendWidth+9,margintop);
				legendBorder.graphics.lineTo(contentWidth+legendWidth+9,margintop+contentHeight+1);
				legendBorder.graphics.lineTo(contentWidth+7,margintop+contentHeight+1);
				legendBorder.graphics.lineTo(contentWidth+7,margintop);
				this.addElement(legendBorder);
				
				var legendGroup:Group = new Group();
				legendGroup.x = 8+contentWidth;
				legendGroup.y = margintop+1;
				legendGroup.height = contentHeight;
				legendGroup.width = legendWidth;
				legendGroup.clipAndEnableScrolling = true;
				this.addElement(legendGroup);
				
				groupCharts.push(chartGroup);
				groupLegends.push(legendGroup);
			}
		}
		
		private function getMaxLegend():int
		{
			var maxLength:int = 0;
			for each(var chartInfo:ChartInfo in chartInfos)
			{
				if(chartInfo.SerialInfos.length >maxLength)
				{
					maxLength = chartInfo.SerialInfos.length;
				}
			}
			return maxLength;
		}
		
		protected function chart_clickHandler(event:MouseEvent):void
		{
			var x:int = event.localX;
			var halfx:int = x/2;
			SelectedPointIndex = halfx;
			if(points!=null && points.length>halfx)
			{
				var eventObject:ChartItemClickEvent = new ChartItemClickEvent("ItemClick",selectedPoint);
				dispatchEvent(eventObject);
			}
		}
		
		private function fireSelectedPointChanged(index:int):void
		{
			for(var i:int=0; i< chartInfos.length; i++)
			{
				try{
					var group:Group = groupCharts[i] as Group;
					var preLine:UIComponent = selLines[i] as UIComponent;
					if(preLine) {
						(preLine.parent as Group).removeElement(preLine);
					}
					var line:UIComponent = new UIComponent();
					group.addElement(line);
					selLines[i] = line;
					line.graphics.lineStyle(2,0xFF8C00);
					line.graphics.moveTo(index*2,0);
					line.graphics.lineTo(index*2,group.height);
				}
				catch(e:Error){}
			}
		}
		protected function this_resizeHandler(event:ResizeEvent):void
		{
			if(this.stage!=null)
			{
				createGroups();
				drawLegend();
				drawGraph();
			}
		}
	}
}		